package com.jeesit.cloud.spot.business.impl.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jeesit.cloud.constants.GdConstants;
import com.jeesit.cloud.dto.*;
import com.jeesit.cloud.model.*;
import com.jeesit.cloud.spot.business.impl.IGdContractBiz;
import com.jeesit.cloud.spot.mapper.GdContractRecordMapper;
import com.jeesit.cloud.spot.service.*;
import com.jeesit.cloud.util.DecimalUtil;
import com.jeesit.cloud.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GdContractBizImpl implements IGdContractBiz {
    @Autowired
    private IGdContractRecordService contractRecordService;
    @Autowired
    private IGdBizOrgService gdBizOrgService;
    @Autowired
    private IGdMaterialRelationService gdMaterialRelationService;
    @Autowired
    private IGdInventoryRecordService gdInventoryRecordService;
    @Autowired
    private IContractService contractService;
    @Autowired
    private IContractDetailService contractDetailService;
    @Autowired
    private IMaterialSpotService materialSpotService;
    /**
     * 同步高达数据
     */
    @Override
    @Transactional
    public void portGd() {
        List<GdBizOrg> gdBizOrgs = gdBizOrgService.list(0, new GdBizOrgDto());
        List<GdMaterialRelation> gdMaterialRelations = gdMaterialRelationService.list(0, new GdMaterialRelationDto());
        Map<String,GdBizOrg> busGroup = gdBizOrgs.stream().collect(Collectors.toMap(GdBizOrg::getName, Function.identity(),(a, b)->a));
        JSONObject objInfo = new JSONObject();
        objInfo.put("contractBillcode", "");
        objInfo.put("datasBalcorp", "");
        objInfo.put("deptCode", "");
        objInfo.put("endDate", "");
        objInfo.put("orgCode", "");
        objInfo.put("startDate", "");
        String encode = String.valueOf(objInfo);
        List<GdContractRecord> purContracts = purContract(encode,gdMaterialRelations,busGroup);//采购
        List<GdContractRecord> saleContracts = saleContract(encode,gdMaterialRelations,busGroup);//销售
        List<GdInventoryRecord> inventoryGds = inventoryGd(encode,gdMaterialRelations,purContracts);//库存
        if(purContracts.size()>0){
            contractRecordService.updateDeleted(0);
            contractRecordService.saveOrUpdateBatch(purContracts);
            updateCon(purContracts,false);//同步采购合同
        }
        if(saleContracts.size()>0){
            contractRecordService.updateDeleted(1);
            contractRecordService.saveOrUpdateBatch(saleContracts);
            updateCon(saleContracts,true);
        }
        if(inventoryGds.size()>0){
            gdInventoryRecordService.deleteDate();
            gdInventoryRecordService.saveOrUpdateBatch(inventoryGds);
        }
    }

    //采购
    private List<GdContractRecord> purContract(String encode,List<GdMaterialRelation> gdMaterialRelations,Map<String,GdBizOrg> busGroup){
        List<GdContractRecord> contractGds = new ArrayList<>();
        try {
            String s = sendPost(GdConstants.url+GdConstants.PUR, encode);

            if (!StringUtil.isBlank(s)) {
                JSONArray item = JSON.parseObject(s).getJSONArray("result");
                //String[] header = new String[]{"合同编号","合同敞口（1合同敞口 2库存敞口）","是否完结(0新增 1完成)","合同量","出库量（签收量）","库存量","业务部门","业务机构","大类","品名","备案状态(0未备案 1已备案)",""};
                //String[] headers = new String[]{"contractBillcode","contractExposure","dataGoodsflag","goodsWeight","deliveryWeight","warehouseGoodsWeight"
                //       ,"deptName" ,"orgName","pntreeName","partsnameName","dataFiling",""};
                //importExe(item,header,headers,0);
                for (Object it : item) {
                    GdContractRecord contractGd = new GdContractRecord();
                    JSONObject its = (JSONObject) it;
                    contractGd.setPurchaseContractNumber(its.getString("contractBillcode").trim());
                    Integer contractExposure = its.getInteger("contractExposure");
                    String dataGoodsflag = its.getString("dataGoodsflag")==null?"":its.getString("dataGoodsflag").trim();//是否已完结
                    if("1".equals(dataGoodsflag)){
                        log.info("导入失败，合同编号："+contractGd.getPurchaseContractNumber()+",已完结");
                        continue;
                    }
                    if(contractExposure==0||"".equals(its.getString("contractBillcode"))){
                        log.info("导入失败，合同编号："+contractGd.getPurchaseContractNumber()+",为无敞口过滤此条数据");
                        continue;
                    }
                    Integer dataFiling = its.getInteger("dataFiling")==null?0:its.getInteger("dataFiling");
                    if(dataFiling==0){
                        log.info("导入失败，合同编号："+contractGd.getPurchaseContractNumber()+",未备案过滤此条数据");
                        continue;
                    }
                    contractGd.setDeliveryWeight(its.getDouble("deliveryWeight")==null?0d:its.getDouble("deliveryWeight"));
                    contractGd.setInventory(its.getDouble("warehouseGoodsWeight")==null?0d:its.getDouble("warehouseGoodsWeight"));
                    contractGd.setWeight(its.getDouble("goodsWeight")==null?0d:its.getDouble("goodsWeight"));
                    contractGd.setType(false);
                    contractGd.setDepartmentName(its.getString("deptName").trim());//deptName
                    contractGd.setExposureFlag(contractExposure==1?"合同敞口":"库存敞口");
                    contractGd.setGroupName(its.getString("orgName").trim());
                    contractGd.setMatterName(its.getString("pntreeName").trim());
                    contractGd.setAddTime(new Date());
                    contractGd.setDescription(its.getString("partsnameName").trim());
                    if(contractExposure==1){
                        Double contractedQuantity =0d;
                        contractedQuantity= DecimalUtil.valueOf(contractGd.getWeight()).subtract(contractGd.getDeliveryWeight()).doubleValue();
                        contractGd.setContractedQuantity(contractedQuantity>0?contractedQuantity:0d);
                    }else {
                        contractGd.setContractedQuantity(contractGd.getInventory()>0?contractGd.getInventory():0d);
                    }
                    contractGd=getBroadHeading(contractGd,gdMaterialRelations);
                    if(busGroup.containsKey(contractGd.getDepartmentName())){
                        GdBizOrg busiGroup = busGroup.get(contractGd.getDepartmentName());
                        contractGd.setGdOrgUuid(busiGroup.getUuid());
                        contractGd.setBizOrgName(busiGroup.getBizOrgName());
                        contractGd.setBizOrgUuid(busiGroup.getBizOrgUuid());
                    } else {
                        log.info("导入失败，合同编号："+contractGd.getPurchaseContractNumber()+",的部门："+contractGd.getDepartmentName()+",在系统没有查询到！");
                        continue;
                    }
                    //if(contractGd.getRelationId()==null){
                    //    log.info("导入失败，合同编号："+contractGd.getPurchaseContractNumber()+",的大类:"+contractGd.getDescription()+"，在系统没有查询到！");
                    //    continue;
                    //}
                    contractGd.setDeleted(Boolean.FALSE);
                    contractGds.add(contractGd);
                }
            }
        } catch (Exception e) {
            // log.info("导入失败,采购合同"+e);
            e.getMessage();
        }
        return contractGds;
    }


    //销售
    private List<GdContractRecord> saleContract(String encode,List<GdMaterialRelation> gdMaterialRelations,Map<String,GdBizOrg> busGroup){
        List<GdContractRecord> contractGds = new ArrayList<>();
        try {
            String s = sendPost(GdConstants.url+GdConstants.SALE, encode);
            if (!StringUtil.isBlank(s)) {
                JSONArray item = JSON.parseObject(s).getJSONArray("result");
                //String[] header = new String[]{"合同编号","合同敞口（1合同敞口 2库存敞口）","是否完结(0新增 1完成)","合同量","合同未出库量","业务部门","业务机构","大类","品名","备案状态(0未备案 1已备案)",""};
                //String[] headers = new String[]{"contractBillcode","contractExposure","dataGoodsflag","goodsWeight","contractDeliveryNweight","deptName"
                //        ,"orgName","pntreeName","partsnameName","dataFiling",""};
                //importExe(item,header,headers,1);
                for (Object it : item) {
                    GdContractRecord contractGd = new GdContractRecord();
                    JSONObject its = (JSONObject) it;
                    String deptName = its.getString("deptName").trim();
                    contractGd.setSaleContractNumber(its.getString("contractBillcode").trim());
                    String dataGoodsflag = its.getString("dataGoodsflag")==null?"":its.getString("dataGoodsflag").trim();//是否已完结
                    if("1".equals(dataGoodsflag)){
                        log.info("导入失败，合同编号："+contractGd.getSaleContractNumber()+",已完结");
                        continue;
                    }
                    Integer contractExposure = its.getInteger("contractExposure")==null?0:its.getInteger("contractExposure");
                    if(contractExposure==0||"".equals(its.getString("contractBillcode"))){
                        log.info("导入失败，合同编号："+contractGd.getSaleContractNumber()+",为无敞口过滤此条数据");
                        continue;
                    }
                    Integer dataFiling = its.getInteger("dataFiling")==null?0:its.getInteger("dataFiling");
                    if(dataFiling==0){
                        log.info("导入失败，合同编号："+contractGd.getSaleContractNumber()+",未备案过滤此条数据");
                        continue;
                    }
                    contractGd.setUnDeliveryWeight(its.getDouble("contractDeliveryNweight")==null?0d:its.getDouble("contractDeliveryNweight"));
                    contractGd.setWeight(its.getDouble("goodsWeight")==null?0d:its.getDouble("goodsWeight"));
                    contractGd.setType(true);
                    contractGd.setDepartmentName(deptName);
                    contractGd.setExposureFlag(contractExposure==1?"合同敞口":"库存敞口");
                    contractGd.setGroupName(its.getString("orgName").trim());
                    contractGd.setMatterName(its.getString("pntreeName").trim());
                    contractGd.setAddTime(new Date());
                    contractGd.setDescription(its.getString("partsnameName").trim());
                    contractGd.setContractedQuantity(contractGd.getUnDeliveryWeight()>0?contractGd.getUnDeliveryWeight():0d);
                    contractGd=getBroadHeading(contractGd,gdMaterialRelations);
                    if(busGroup.containsKey(contractGd.getDepartmentName())){
                        GdBizOrg busiGroup = busGroup.get(contractGd.getDepartmentName());
                        contractGd.setGdOrgUuid(busiGroup.getUuid());
                        contractGd.setBizOrgName(busiGroup.getBizOrgName());
                    } else {
                        log.info("导入失败，合同编号："+contractGd.getSaleContractNumber()+",的部门："+contractGd.getDepartmentName()+",在系统没有查询到！");
                        continue;
                    }
                    //if(contractGd.getRelationId()==null){
                    //    log.info("导入失败，合同编号："+contractGd.getSaleContractNumber()+",的大类:"+contractGd.getDescription()+"，在系统没有查询到！");
                    //    continue;
                    //}
                    contractGd.setDeleted(Boolean.FALSE);
                    contractGds.add(contractGd);
                }
            }
        } catch (Exception e) {
            log.info("导入失败,销售合同"+e.getMessage());
        }
        return contractGds;
    }

    //库存
    private List<GdInventoryRecord> inventoryGd(String encode, List<GdMaterialRelation> gdMaterialRelations, List<GdContractRecord> purContracts){
        List<GdInventoryRecord> inventoryGdList = new ArrayList<>();
        try {
            String s = sendPost(GdConstants.url+GdConstants.INVENTORY, encode);

            if (!StringUtil.isBlank(s)) {
                JSONArray item = JSON.parseObject(s).getJSONArray("result");
                Map<String,GdContractRecord> conGroup = purContracts.stream().collect(Collectors.toMap(GdContractRecord::getPurchaseContractNumber,Function.identity(),(a,b)->a));
                for (Object it : item) {
                    ObjectMapper objectMapper = new ObjectMapper();
                    GdInventoryRecord inventoryGd = objectMapper.readValue(it.toString(), GdInventoryRecord.class);
                    if(conGroup.containsKey(inventoryGd.getGoodsContractold().trim())&&inventoryGd.getGoodsWeight().doubleValue()>0) {
                        GdContractRecord gdContractRecord = conGroup.get((inventoryGd.getGoodsContractold().trim()));
                        inventoryGd.setAddTime(new Date());
                        inventoryGd.setDeleted(false);
                        inventoryGd.setGoodsContractold(inventoryGd.getGoodsContractold().trim());
                        inventoryGd.setBizOrgName(gdContractRecord.getBizOrgName());
                        inventoryGd.setBizOrgUuid(gdContractRecord.getBizOrgUuid());
                        inventoryGd.setCatalogName(gdContractRecord.getCatalogName());
                        inventoryGdList.add(inventoryGd);
                    }
                }
            }
        } catch (Exception e) {
            log.info("库存d导入失败"+e.getMessage());
        }
        return inventoryGdList;
    }


    private String sendPost(String url,String encode) throws MalformedURLException {
        URL realUrl = new URL(url);
        // 打开和URL之间的连接
        String result = "";
        URLConnection conn = null;
        PrintWriter out = null;
        BufferedReader in = null;
        try {
            conn = realUrl.openConnection();

            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "UTF-8");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(encode);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            in.close();
        } catch (IOException e) {
            return result;
        }finally {
            out.close();
        }
        return result;
    }

    // 查询所属大类
    public  GdContractRecord getBroadHeading(GdContractRecord it,List<GdMaterialRelation> gdMaterialRelations){
        for(int i=0;i<gdMaterialRelations.size();i++){
            GdMaterialRelation its = gdMaterialRelations.get(i);
            if(its.getGeneralities().contains(it.getMatterName())){
                if(!StringUtil.isBlank(its.getKeyword()) &&
                        (StringUtil.isBlank(its.getNotKeyword())|| !it.getDescription().contains(its.getNotKeyword()))){//关键字不是空，并且排除关键字是空或者排除关键字不包含品名
                    String[] keywords = its.getKeyword().split(",");
                    for(String k:keywords){
                        if(it.getDescription().contains(k)){
                            it.setGdRelationUuid(its.getUuid());
                            it.setCatalogName(its.getCatalogName());
                            continue;
                        }
                    }
                }
                if(StringUtil.isBlank(its.getKeyword())){
                    it.setGdRelationUuid(its.getUuid());
                    it.setCatalogName(its.getCatalogName());
                }
            }
        }
        return it;
    }

    //第三方数据同步本地合同
    public void updateCon(List<GdContractRecord> gdContract,Boolean isCon){
        ContractDto contractDto = new ContractDto();
        contractDto.setIsContract(isCon);
        List<Contract> contracts = contractService.list(0, contractDto);
        List<ContractDetail> contractDetails = contractDetailService.list(0, new ContractDetailDto());
        List<GdMaterialRelation> gdMaterialRelations = gdMaterialRelationService.list(0,new GdMaterialRelationDto());
        List<MaterialSpot> materialRelations = materialSpotService.list(0,new MaterialSpotDto());
        for(MaterialSpot it : materialRelations){
            it.setCatalogSpot(it.getCatalogName()+it.getCatalogName());
        }
        Map<String,MaterialSpot> spotGroup = materialRelations.stream().collect(Collectors.toMap(MaterialSpot::getCatalogSpot,Function.identity(),(a,b)->a));
        Map<Long,GdMaterialRelation> relationGroup = gdMaterialRelations.stream().collect(Collectors.toMap(GdMaterialRelation::getUuid,Function.identity(),(a,b)->a));
        Map<String,Contract> contGroup =  contracts.stream().collect(Collectors.toMap(Contract::getContractNumber,Function.identity(),(a,b)->a));//根据合同编号分组
        Map<String,ContractDetail> detailGroup =  contractDetails.stream().collect(Collectors.toMap(ContractDetail::getContractNumber,Function.identity(),(a,b)->a));//根据合同编号分组
        List<Contract> contractList = new ArrayList<>();
        List<ContractDetail> contractDetailList = new ArrayList<>();
         for(GdContractRecord it : gdContract){
             String contractNumber = isCon?it.getSaleContractNumber():it.getPurchaseContractNumber();
             if(contGroup.containsKey(contractNumber)){//如果系统里面有对应合同更新重量，没有插入一条数据
                 Contract contract = contGroup.get(contractNumber);
                 contract.setModTime(new Date());
                 contract.setBizOrgUuid(it.getBizOrgUuid());
                 contract.setWeight(it.getWeight());
                 if(detailGroup.containsKey(contractNumber)){
                     ContractDetail contractDetail = detailGroup.get(contractNumber);
                     contractDetail.setWeight(it.getWeight());
                     contractDetail.setSpotOpen(it.getContractedQuantity());
                     contractDetailList.add(contractDetail);
                 }
                 contractList.add(contract);
                 contGroup.remove(contractNumber);
             }else {
                 Contract contract = new Contract();
                 contract.setAddTime(new Date());
                 contract.setDeleted(false);
                 contract.setSubmitState(true);
                 contract.setIsContract(isCon);
                 contract.setContractNumber(contractNumber);
                 contract.setContractNumberExternal(contractNumber);
                 contract.setContractType(1);

                 contract.setContractDate(new Date());
                 if(relationGroup.containsKey(it.getGdRelationUuid())) {
                     GdMaterialRelation gdMaterialRelation = relationGroup.get(it.getGdRelationUuid());
                     contract.setCatalogName(gdMaterialRelation.getCatalogName());
                     contract.setCatalogUuid(gdMaterialRelation.getCatalogUuid());
                 }
                 contract.setContractStatus(0);
                 contract.setOpenStatus(it.getExposureFlag().equals("合同敞口")?0:1);
                 contract.setBizOrgName(it.getBizOrgName());
                 contract.setBizOrgUuid(it.getBizOrgUuid());
                 contract.setWeight(it.getWeight());
                 contract.setCheckStatus(1);
                 contract.setIsCompleted(false);
                 contract.setIsScheme(false);
                 contractService.saveOrUpdate(contract);
                 ContractDetail contractDetail = new ContractDetail();
                 contractDetail.setMaterialCatalogName(contract.getCatalogName());
                 contractDetail.setMaterialCatalogUuid(contract.getCatalogUuid());
                 if(spotGroup.containsKey(contract.getCatalogName()+contract.getCatalogName())) {
                     MaterialSpot materialSpot = spotGroup.get(contract.getCatalogName()+contract.getCatalogName());
                     contractDetail.setMaterialSpotName(materialSpot.getName());
                     contractDetail.setMaterialSpotUuid(materialSpot.getUuid());
                 }
                 contractDetail.setWeightType(1);
                 contractDetail.setWeight(it.getWeight());
                 contractDetail.setContractUuid(contract.getUuid());
                 contractDetail.setSpotOpen(it.getContractedQuantity());
                 contractDetail.setDeleted(false);
                 contractDetail.setAddTime(new Date());
                 contractDetailService.saveOrUpdate(contractDetail);
             }
         }
         for(String ket: contGroup.keySet()){//剩下的合同是新数据没有的合同，也就是已完结状态的
             Contract contract = contGroup.get(ket);
             if(contract.getAddUserUuid()==null){//测试环境自己会添加合同不改状态
                 contract.setIsCompleted(true);
                 contractList.add(contract);
             }
         }
         contractService.saveOrUpdateBatch(contractList);
        contractDetailService.saveOrUpdateBatch(contractDetailList);
    }

}
